﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Silverstone.DI
{
    /// <summary>
    ///     Provides an interface for a class used to register and resolve dependencies at runtime
    /// </summary>
    public interface IContainer
    {
        /// <summary>
        ///     Registers the specified concrete type against itself for creation.
        /// </summary>
        /// <typeparam name="TConcrete">The concrete type to register.</typeparam>
        void RegisterSelf<TConcrete>();

        /// <summary>
        ///     Registers the specified concrete type against the specified abstract type for creation, using the
        ///     default creation strategy.
        /// </summary>
        /// <typeparam name="TConcrete">The concrete type to register.</typeparam>
        /// <typeparam name="TAbstract">The abstract type to register.</typeparam>
        void RegisterForCreation<TConcrete, TAbstract>();

        /// <summary>
        ///     Registers the specified concrete type against the specified abstract type for creation, using the
        ///     specified creation strategy.
        /// </summary>
        /// <typeparam name="TConcrete">The concrete type to register</typeparam>
        /// <typeparam name="TAbstract">The abstract type to register</typeparam>
        /// <param name="creationStrategy">The creation strategy to use when creating the instance.</param>
        void RegisterForCreation<TConcrete, TAbstract>(ICreationStrategy creationStrategy);

        /// <summary>
        ///     Registers the specified instance against the specified abstract type to be used every time
        ///     the type is requested.
        /// </summary>
        /// <typeparam name="TAbstract">The abstract type to register.</typeparam>
        /// <param name="instance">The instance which implements/inherits the abstract type.</param>
        void RegisterInstance<TAbstract>(TAbstract instance);

        /// <summary>
        ///     Gets the concrete implementation of the specified abstract type.
        /// </summary>
        /// <typeparam name="TAbstract">The abstract type to register</typeparam>
        /// <returns>The resolved instance, or null if not found</returns>
        TAbstract Get<TAbstract>();
    }
}
